package com.pclong.doudizhu.server.demo1;

/**
 * Description:
 * </br>Copyright (C), 2005-2009, KK
 * </br>This program is protected by copyright laws.
 * </br>Program name: DouDiZhu
 * </br>Date: 12/10/09
 * @author kk
 * @version 1.0
 */

class Round {
	private Seat[] seats;
	private Poker poker;
	private int actioner; // the current turn (donated by the index of seat in array)
	private int dizhu; // dizhu of the current round (donated by the index of seat in array)
	
	public Round()
	{
		this.seats = null;
		this.poker = new Poker();
		this.actioner = -1;
		this.dizhu = -1;
	}
	public Round(Seat[] seats, Poker poker)
	{
		this.seats = seats;
		this.poker = poker;
		this.actioner = -1;
		this.dizhu = -1;
		// according to the history to decide the first actioner
		for(int i=0; i<seats.length; i++)
			if(seats[i].wasWin())
			{
				this.actioner = i;
				break;
			}
		if(actioner == -1)
			this.actioner = 0;
	}
	
	protected void turnNext()
	{
		actioner = (++actioner)%seats.length;
	}
	
	public void run()
	{
		// 1. shuffle the poker cards
		poker.shuffle();
		// 2. deal the cards to each person
		int n;
		for(n=0; n<poker.getNumOfCards()-3;n++)
		{
			seats[actioner].getPlayer().receiveCard(poker.getCardAt(n));
			turnNext();
		}
		// 3. call DiZhu
		int i;
		for(i=0; i<3; i++)
		{
			if(seats[actioner].getPlayer().call() == true)
			{
				// give the dizhu last three cards
				seats[actioner].getPlayer().receiveCard(poker.getCardAt(n));
				seats[actioner].getPlayer().receiveCard(poker.getCardAt(n+1));
				seats[actioner].getPlayer().receiveCard(poker.getCardAt(n+2));
				dizhu = actioner;
				
				turnNext();
				seats[actioner].getPlayer().setRole(1);
				turnNext();
				seats[actioner].getPlayer().setRole(-1);
				turnNext();
				break;
			}
			else
				turnNext();
		}
		if(i == 3)
		{
			System.out.println("Restart!");
			return;
		}
		// 4. play
		DDZHandCards nowTurn = new DDZHandCards();
		DDZHandCards lastTurn = new DDZHandCards();
		DDZHandCards beforLastTurn = new DDZHandCards();
		while(seats[0].getPlayer().getCardNum() != 0
				&& seats[1].getPlayer().getCardNum()!=0
				&& seats[2].getPlayer().getCardNum()!=0)
		{
			seats[0].getPlayer().printCardsOnHand();
			seats[1].getPlayer().printCardsOnHand();
			seats[2].getPlayer().printCardsOnHand();
			
			if(lastTurn.getCardsType().type == DDZHandCardsType.DDZTypes.NONE)
				nowTurn = seats[actioner].getPlayer().playCards(beforLastTurn);
			else
				nowTurn = seats[actioner].getPlayer().playCards(lastTurn);
			beforLastTurn = lastTurn;
			lastTurn = nowTurn;
			
			System.out.print("Player "+seats[actioner].getPlayer().getName()+" plays: ");
			nowTurn.print();
			System.out.print("\n");
			
			turnNext();
		}
		// 5. end
		if(seats[dizhu].getPlayer().getCardNum() == 0) // dizhu wins
		{ 
			actioner = dizhu;
			seats[actioner].getPlayer().changeScore(2);
			seats[actioner].setWin(true);
			turnNext();
			seats[actioner].getPlayer().changeScore(-1);
			seats[actioner].setWin(false);
			turnNext();
			seats[actioner].getPlayer().changeScore(-1);
			seats[actioner].setWin(false);
			System.out.println("The winner is DiZhu!");
		}
		else
		{
			actioner = dizhu;
			seats[actioner].getPlayer().changeScore(-2);
			seats[actioner].setWin(false);
			turnNext();
			seats[actioner].getPlayer().changeScore(1);
			seats[actioner].setWin(true);
			turnNext();
			seats[actioner].getPlayer().changeScore(1);
			seats[actioner].setWin(true);
			System.out.println("The winner are NongMins!");
		}
		
		return;
	}
}

class Seat {
	private int id;
	private Player p;
	private boolean free;
	private boolean win;
	
	public Seat()
	{
		this.id = 0;
		this.free = true;
		this.p = null;
		this.win = true;
	}
	public Seat(int id)
	{
		this.id = id;
		this.free = true;
		this.win = true;
	}
	
	public boolean takenBy(Player p)
	{
		if(this.free == false)
			return false;
		else
		{
			this.p = p;
			this.free = false;
			return true;
		}
	}
	
	public boolean isFree()
	{
		return this.free;
	}
	
	public boolean wasWin()
	{
		return this.win;
	}
	
	public void setWin(boolean win)
	{
		this.win = win;
	}
	
	public Player getPlayer()
	{
		if(this.free == false)
			return this.p;
		else
			return null;
	}
	
	public int getID()
	{
		return this.id;
	}
}

public class Game {
	private final int NUM_SEATS = 3;
	private Seat[] seats;
	private Poker poker;
	private int roundNum;
	private boolean stop;
	
	public Game()
	{
		this.seats = new Seat[NUM_SEATS];
		for(int i=0; i<NUM_SEATS; i++)
			this.seats[i] = new Seat(i);
		this.poker = new Poker();
		this.roundNum = 0;
		this.stop = false;
	}
	
	public void start()
	{
		boolean seatsFull=true; // all the seats are taken
		boolean canStart=true; // all the scores of the players on seats are bigger than zero
		for(Seat s : this.seats)
		{
			if(s.isFree()==true)
				seatsFull = false;
			if(s.getPlayer().getScore()<=0)
				canStart = false;
		}
		while(seatsFull && canStart && !this.stop)
		{
			Round r = new Round(this.seats, this.poker);
			r.run();
			this.roundNum++;
			
			for(Seat s : this.seats)
			{
				if(s.isFree()==true)
					seatsFull = false;
				if(s.getPlayer().getScore()<=0)
					canStart = false;
			}
		}
	}
	
	public Seat[] getSeats()
	{
		return this.seats;
	}

}
